const fs = require('fs');
const path = require('path');
const spawn = require('child_process').spawn;
const md5File = require('md5-file');

exports.CommandReplace = {
    DATA: {
        source: '', // the source jar absolute path
        resource: '', // the resource file/dir absolute path
        detail: false,
        message: null 
    },
    DETAIL: [],
    FLAG: true,
    step1Init: (options) =>{
        if (null == options.source) {
            error('Your must tell me the source path!');
            return;
        } 
        if (null == options.resource) {
            error('Your must tell me the resource path!');
            return;
        }
    
        LOG.consoleInfo('Get source path: ' + options.source);
        LOG.consoleInfo('Get resource path: ' + options.resource);
        DATA.source = options.source;
        DATA.resource = options.resource;
        DATA.detail = options.detail;
        DATA.message = options.message;
        step2ResourceCheck();
    },
    step2ResourceCheck: () => {
        try {
            if (!fs.existsSync(DATA.source)) {
                error('The source file does not exit!!!!');
                return;
            }
            const sourceState = fs.lstatSync(DATA.source);
            if(sourceState.isDirectory()) {
                error('The source file should be a jar file! Not directory!!!!');
                return;
            }
            if (!fs.existsSync(DATA.resource)) {
                error('The resource ['+DATA.resource+'] does not exist!!!!!');
                return;
            }
            const resourceState = fs.lstatSync(DATA.resource);
            if (resourceState.isDirectory()) {
                const children = fs.readdirSync(DATA.resource);
                if (children.length == 0) {
                    error('The resource dir is a empty dir!');
                }
            }
            LOG.consoleInfo("Check source OK!");
            LOG.consoleInfo("Check resource OK!");
            step3ReplaceResource();
        }catch(err) {
            error('Check source/resource failed! Error message:');
            error(err);
            return;
        }
    },
    step3ReplaceResource:()=>{
        const child = spawn('jar', ['-uvf0', DATA.source, DATA.resource ]);
        recordDetail('SOURCE: ' + DATA.source);
        recordDetail('RESOURCE: ' + DATA.resource);
        recordDetail('MD5 (Before replacement): '+ md5File.sync(DATA.source));
        LOG.consoleInfo("Preparing replacement with command 'jar'....");
        LOG.consoleInfo(null, false);
        child.stdout.on('data', function(chunk) {
            LOG.consoleInfo(chunk, false);
        });
        child.stderr.on('data', function(data) {
            error(data, false);
        });
        child.stdout.on('close', function(code) {
            LOG.consoleInfo('*****Replace finished with status: '+FLAG+'! See log for detail ⬆️!');
            recordDetail('MD5 (After replacement): '+ md5File.sync(DATA.source));
            LOG.consoleInfo(null, false);
            if (FLAG) {
                recordSink();
            }
        });
    },
    recordDetail: (text = null)=> {
        if (text) {
            DETAIL.push(text);
        } else {
            DETAIL.push('========================================');
        } 
    },
    error: (text, withType = true)=> {
        if (FLAG) {
            FLAG = false;
        }
        LOG.consoleError(text, withType);
    },
    recordSink:() =>{
        if (DATA.detail) {
            if (DATA.message) {
                recordDetail('MESSAGE: ' + DATA.message);
            }
            const detailFilePath = path.dirname(DATA.source);
            const detailLogPath = detailFilePath + path.sep + 'jaer-replace.jaer';
            LOG.consoleInfo('Do record sink!! ' + detailLogPath);
            recordDetail(null);
            fs.appendFile(detailLogPath, DETAIL.join('\r\n'), function() {
                LOG.consoleInfo('Record sink finished!');
            });
        }
    }
}